
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
using namespace std;

#define I(i,n) for (int i = 0; i < n; ++ i)

class SVG_Object {
public:
	string fill;
	string stroke;
	string stroke_width;
	string transform_origin;
	string transform;
	string _attrs() const {
		stringstream ss;
		if (fill.size()>0)
			ss << "fill=\"" << fill << "\" ";
		if (stroke.size()>0)
			ss << "stroke=\"" << stroke << "\" ";
		if (transform_origin.size()>0)
			ss << "transform-origin=\"" << transform_origin << "\" ";
		if (transform.size()>0)
			ss << "transform=\"" << transform << "\" ";
		if (stroke_width.size()>0)
			ss << "stroke-width=\"" << stroke_width << "\" ";
		return ss.str();	
	}
	virtual string html() const = 0;
};

class SVG {
	vector<string> elements;
public:
	string width;
	string height;
	SVG() : width("800"), height("600") {}
	SVG & operator += (const SVG_Object & shape) {
		elements.push_back(shape.html());
		return *this;
	}
	string html() const {
		stringstream ss;
		ss << "<svg width=\""<<width<<"\" height=\""<<height
			<< "\" xmlns=\"http://www.w3.org/2000/svg\">\n";
		I(i, elements.size())
			ss << "\t" << elements[i] << endl;
		ss << "</svg>\n";
		return ss.str();		
	}
};

ostream & operator << (ostream & o, const SVG & svg) {
	o << svg.html();
	return o;
}

// <circle cx="25" cy="75" r="20" stroke="red" fill="transparent" stroke-width="5"/>
class circle : public SVG_Object {
public:
	string cx;
	string cy;
	string r;
	string html() const {
		stringstream ss;
		ss << "<circle cx=\""<<cx<<"\" cy=\""<<cy<<"\" r=\""<<r<<"\" "
			<<_attrs()<<" />";
		return ss.str();
	}
};

// <rect x="10" y="10" width="30" height="30" stroke="black" fill="transparent" stroke-width="5"/>
class rect : public SVG_Object {
public:
	string x;
	string y;
	string rx;
	string ry;
	string width;
	string height;
	string html() const {
		stringstream ss;
		ss << "<rect x=\""<<x<<"\" y=\""<<y<<"\" ";
		if (rx.size()>0 and ry.size()>0)
			ss <<"rx=\""<<rx<<"\" ry=\""<<ry<<"\" ";
		ss <<"width=\""<<width<<"\" height=\""<<height<<"\" "
			<<_attrs()<<" />";
		return ss.str();
	}
};

// <ellipse cx="75" cy="75" rx="20" ry="5" stroke="red" fill="transparent" stroke-width="5"/>
class ellipse : public SVG_Object {
public:
	string cx;
	string cy;
	string rx;
	string ry;
	string html() const {
		stringstream ss;
		ss << "<ellipse cx=\""<<cx<<"\" cy=\""<<cy<<"\" "
			<<"rx=\""<<rx<<"\" ry=\""<<ry<<"\" "
			<<_attrs()<<" />";
		return ss.str();
	}
};

// <line x1="10" x2="50" y1="110" y2="150" stroke="orange" stroke-width="5"/>
class line : public SVG_Object {
public:
	string x1;
	string y1;
	string x2;
	string y2;
	string html() const {
		stringstream ss;
		ss << "<line x1=\""<<x1<<"\" y1=\""<<y1<<"\" "
			<<"x2=\""<<x2<<"\" y2=\""<<y2<<"\" "
			<<_attrs()<<" />";
		return ss.str();
	}
};

// <polyline points="60 110 65 120 70 115 75 130 80 125 85 140 90 135 95 150 100 145"
// stroke="orange" fill="transparent" stroke-width="5"/>
class polyline : public SVG_Object {
public:
	string points;
	string y1;
	string x2;
	string y2;
	string html() const {
		stringstream ss;
		ss << "<polyline points=\"" << points
			<< "\" "<<_attrs()<<" />";
		return ss.str();
	}
};

// <polygon points="50 160 55 180 70 180 60 190 65 205 50 195 35 205 40 190 30 180 45 180"
// stroke="green" fill="transparent" stroke-width="5"/>
class polygon : public SVG_Object {
public:
	string points;
	string y1;
	string x2;
	string y2;
	string html() const {
		stringstream ss;
		ss << "<polygon points=\"" << points
			<< "\" "<<_attrs()<<" />";
		return ss.str();
	}
};

// <text x="10" y="10">Hello World!</text>
class text : public SVG_Object {
public:
	string x;
	string y;
	string content;
	string font_family;
	string font_style;
	string font_weight;
	string font_variant;
	string font_stretch;
	string font_size;
	string font_size_adjust;
	string kerning;
	string letter_spacing;
	string word_spacing;
	string text_decoration;
	string html() const {
		stringstream ss;
		ss << "<text x=\""<<x<<"\" y=\""<<y<<"\" ";
		if (font_family.size()>0)
			ss << "font-family=\"" << font_family << "\" ";
		if (font_style.size()>0)
			ss << "font-style=\"" << font_style << "\" ";
		if (font_weight.size()>0)
			ss << "font-weight=\"" << font_weight << "\" ";
		if (font_variant.size()>0)
			ss << "font-variant=\"" << font_variant << "\" ";
		if (font_stretch.size()>0)
			ss << "font-stretch=\"" << font_stretch << "\" ";
		if (font_size.size()>0)
			ss << "font-size=\"" << font_size << "\" ";
		if (font_size_adjust.size()>0)
			ss << "font-size-adjust=\"" << font_size_adjust << "\" ";
		if (kerning.size()>0)
			ss << "kerning=\"" << kerning << "\" ";
		if (letter_spacing.size()>0)
			ss << "letter-spacing=\"" << letter_spacing << "\" ";
		if (word_spacing.size()>0)
			ss << "word-spacing=\"" << word_spacing << "\" ";
		if (text_decoration.size()>0)
			ss << "text-decoration=\"" << text_decoration << "\" ";
		ss << "\" "<<_attrs()<<">"<<content<<"</text>";
		return ss.str();
	}

};
